package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.PublishVo;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 圈子服务实现类
 *      发布动态
 *      好友动态
 *      推荐动态
 */
@Service
public class PublishApiImpl implements PublishApi{

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 发布动态
     */
    @Override
    public String savePublish(PublishVo publishVo) {
        Long currentUserId = publishVo.getUserId();//当前用户id
        long nowTime = System.currentTimeMillis();
        //1.发布动态表-保存
        Publish publish = new Publish();
        BeanUtils.copyProperties(publishVo,publish);//userId textContent longitude latitude medias
        publish.setId(ObjectId.get());//手动设置id
        publish.setPid(1L);//没有用到
        publish.setSeeType(1);//公开
        publish.setLocationName(publishVo.getLocation());//位置名称
        publish.setCreated(nowTime);//发布动态时间
        mongoTemplate.save(publish);
        //2.相册表-保存  quanzi_album_2
        Album album = new Album();
        album.setPublishId(publish.getId());//发布id
        album.setCreated(nowTime);//创建时间
        mongoTemplate.save(album,"quanzi_album_"+currentUserId);//我的相册表
        //3.好友表-查询好友ids tanhua_users（异步处理-进行解耦-MQ）
        Query queryFriend = new Query();
        queryFriend.addCriteria(Criteria.where("userId").is(currentUserId));
        List<Friend> friendList = mongoTemplate.find(queryFriend, Friend.class);
        if(!CollectionUtils.isEmpty(friendList)){
            for (Friend friend : friendList) {
                Long friendId = friend.getFriendId();//好友id
                //4.好友时间线表-保存 quanzi_time_line_1
                TimeLine timeLine = new TimeLine();
                timeLine.setUserId(currentUserId);//好友id
                timeLine.setPublishId(publish.getId());//发布id
                timeLine.setCreated(nowTime);//创建时间
                mongoTemplate.save(timeLine,"quanzi_time_line_"+friendId);//好友时间线表
            }
        }
        return publish.getId().toHexString();
    }

    /**
     * 好友动态
     */
    @Override
    public PageResult<Publish> queryPublishByPage(int page, int pagesize, Long userId) {
        //1.分页查询时间线表
        Query query = new Query();
        query.limit(pagesize).skip((long) (page - 1) *pagesize);
        query.with(Sort.by(Sort.Direction.DESC,"created"));//降序 将时间最新的在最上面展示
        long counts = mongoTemplate.count(query, "quanzi_time_line_" + userId);
        List<TimeLine> timeLineList = mongoTemplate.find(query,TimeLine.class,"quanzi_time_line_" + userId);
        //2.根据时间线表中 发布id  查询发布表数据
        //将 List<TimeLine>转为List<Publish>
        List<Publish> publishList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(timeLineList)){
            for (TimeLine timeLine : timeLineList) {
                ObjectId publishId = timeLine.getPublishId();//发布id
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                if(!StringUtils.isEmpty(publish)) {
                    publishList.add(publish);
                }
            }
        }
        //3.封装分页对象返回
        long pages = (counts / pagesize) + (counts%pagesize > 0 ? 1:0);
        return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
    }

    /**
     * 推荐动态（陌生人动态）
     */
    @Override
    public PageResult<Publish> queryPublishByRecommendQuanzi(int page, int pagesize, Long userId) {
        //1.分页查询推荐动态表
        Query query = new Query();
        query.limit(pagesize).skip((long) (page - 1) *pagesize);
        query.addCriteria(Criteria.where("userId").is(userId));//根据userId查询
        query.with(Sort.by(Sort.Direction.DESC,"created"));//降序 将时间最新的在最上面展示
        long counts = mongoTemplate.count(query, RecommendQuanzi.class);
        List<RecommendQuanzi> recommendQuanziList = mongoTemplate.find(query,RecommendQuanzi.class);
        //2.根据时间线表中 发布id  查询发布表数据
        //将 List<RecommendQuanzi>转为List<Publish>
        List<Publish> publishList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(recommendQuanziList)){
            for (RecommendQuanzi recommendQuanzi : recommendQuanziList) {
                ObjectId publishId = recommendQuanzi.getPublishId();//发布id
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                if(!StringUtils.isEmpty(publish)) {
                    publishList.add(publish);
                }
            }
        }
        //3.封装分页对象返回
        long pages = (counts / pagesize) + (counts%pagesize > 0 ? 1:0);
        return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
    }

    /**
     * 用户动态
     * 1.首页推荐用户列表-点击用户进入会查询用户动态
     * 2.我的模块-我的动态-查看当前用户动态
     */
    @Override
    public PageResult<Publish> queryPublishByAlbum(int page, int pagesize, Long userId) {
        //1.分页查询相册表
        Query query = new Query();
        query.limit(pagesize).skip((long) (page - 1) *pagesize);
        query.with(Sort.by(Sort.Direction.DESC,"created"));//降序 将时间最新的在最上面展示
        long counts = mongoTemplate.count(query, "quanzi_album_"+userId);//
        List<Album> albumList = mongoTemplate.find(query,Album.class,"quanzi_album_"+userId);
        //2.根据相册表中的 发布id  查询发布表数据
        //将 List<Album>转为List<Publish>
        List<Publish> publishList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(albumList)){
            for (Album album : albumList) {//循环遍历相册表 根据发布id查询动态发布表
                ObjectId publishId = album.getPublishId();//发布id
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                if(!StringUtils.isEmpty(publish)) {
                    publishList.add(publish);
                }
            }
        }
        //3.封装分页对象返回
        long pages = (counts / pagesize) + (counts%pagesize > 0 ? 1:0);
        return new PageResult<>(counts,(long)pagesize,pages,(long)page,publishList);
    }

    /**
     * 单条动态查询
     */
    @Override
    public Publish querySinglePublish(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId), Publish.class);
    }

    /**
     * 根据发布id更新动态状态
     * @param publishId
     * @param state
     */
    @Override
    public void updatePublish(String publishId, Integer state) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(new ObjectId(publishId)));
        Update update = new Update();
        update.set("state",state);
        mongoTemplate.updateFirst(query,update,Publish.class);
    }
}
